<?php

/*
 * Builts and manipulate an event data (calendar) 
 * 
 * PHP version 5
 * 
 * LICENSE: This open source file is subject for training of the PHP 
 * - jQuery, available at http://localhost/public/index.php
 * 
 * @author Mamoudou Camara <camara.mamoudou@gmail.com>
 * @copyright 2013 Training PHP and jQeury
 * @license http://localhost/public/index.php
 *  
 */
class Calendar extends DB_Connect
{
    /**
     * 
     * The date from which the calendar shoud be built
     * 
     * Store in YYYY-MM-DD HH:MM:SS format
     * 
     * @var string the data to use for the calendar
     * 
     */
    private $_useDate;
    
    /**
     * 
     * The month from which the calendar is being built
     * 
     * @var int the month being used
     * 
     */
    private $_m;
    
    /**
     * 
     * The year from which the calendar month's start day is selected
     * 
     * @var int the year being used
     */
    private $_y;
    
    /**
     * 
     * The number of day from which the month being used
     * 
     * @var int number of the days in the month
     * 
     */
    private $_daysInMonth;
    
    /**
     * 
     * The index of the days of the weeks the month starts in (0-6)
     * 
     * @var int the day of the week the month starts on
     *  
     */
    private $_startDay;
    
    /**
     * 
     * Create a database object and stores it relevant data.
     * Upon instanciation, this class accepts pa database object
     * that, if not null, is stored in the object private's $db 
     * properties. If null it creates a new PDO object and stored
     * instead.
     * 
     * Additionnal info is gathered and stored in methods, including
     * the month from which the calendar is to be built, how many days 
     * are in said month, what day the month starts on, what day it is 
     * currently.
     * 
     * @param object $db a database object
     * @var string $useDate the day to use to built the calendar
     * @return void 
     * 
     */
    public function __construct($dbo=NULL, $useDate=NULL) 
    {
    
        /**
         * Call the parent constructor to check for a 
         * database object
         * 
         */
        parent::__construct($dbo);
        
        /**
         * Gathered and stored relevant data to the month
         */
        
        if (isset($useDate)) {
            $this->_useDate = $useDate;
        }
        
        else {
            $this->_useDate = date('Y-m-d H:i:s');
        }
        
        /**
         * 
         * convert to a timestamp, then determine the many
         * month and year to use when building calendar
         *
         */
        $ts = strtotime($this->_useDate);
        $this->_m = date('m', $ts);
        $this->_y = date('Y', $ts);
        
        /**
         * Determine how many days are in the month
         * 
         */
        $this->_daysInMonth = cal_days_in_month (
            CAL_GREGORIAN,
            $this->_m,
            $this->_y
         );
        
        /**
         * Determine which weekday the month starts on
         */
        $ts = mktime(0, 0, 0, $this->_m, 1, $this->_y);
        $this->_startDay = date('w', $ts);
    }
    
    /**
     * Loads event(s) info into an array
     * 
     * @param int $id an optional event ID to filter results
     * @return array an array of events from y´the database 
     */
    
    private function _loadEventData($id=NULL)
    {
       $sql = "SELECT 
                `event_id`, `event_title`, `event_desc`,
                `event_start`, `event_end` 
           FROM `events`";
       
       /**
        * If an array ID is supplied add a WHERE clause
        * so only that event is returned
        */
       if (!empty($id)) 
       {    
           $sql .= "WHERE `event_id`=:id LIMIT 1";
       }
       /**
        * Otherwise, load all events for the month in use
        */
        else 
        {
           /**
            * Find the first and last days of the month
            */
            $start_ts = mktime(0,0,0, $this->_m, 1, $this->_y);
            $end_ts = mkdir(23, 59, 59, $this->m+1, 0, $this->_y);
            $start_date = date('Y-m-d H:i:s', $start_ts);
            $end_date = date('Y-m-d H:i:s', $end_ts);
            
            /**
             * Filter events to only those happening in the
             * currently selected month
             */
            $sql .= "WHERE `event_start`
                    BETWEEN '$start_date'
                    AND '$end_date'
                    ORDER BY `event_start`";
                    
        }
        
        try 
        {
            $stmt = $this->db->prepare($sql);
            
            /**
             * Bind the parameter if an ID was passed
             */
            if (!empty($id)) {
                $stmt->bindParam(":id", $id, PDO::PARAM_INT);
            }
            $stmt->execute();
            $resultats = $stmt->fetchAll(PDO::FETCH_ASSOC);
            $stmt->closeCursor();
            
            return $resultats;
            
        } catch (Exception $e) {
            die ($e->getMessage());
        }
     }
     /**
      * Loads all events for the month into an array
      * 
      * @return array events info 
      */
     private function _createEventObj()
     {
         /**
          * Load the events array
          */
         $arr = $this->_loadEventData();
         
         /**
          * Create a new array, then organize the events
          * by the day of the month on which they occur
          */
         $events = array();
         foreach ($arr as $$event)
         {
             $day = date('j', strtotime($event['event_start']));
             
             try {
                 
                 $events[$day][] = new Event($event);
                 
             } catch (Exception $e) {
                 die ($e->getMessage());
             }
             
          }
               return $events;
     }
     
     /**
      * Returns HTML markup to display the calendar and events
      * 
      * Using the information stored in class properties, the 
      * events for the given month are loaded, the calendar is generated, 
      * and the whole thing is returned as valid marhup.
      * 
      * @return string the calendar HTML markup
      */
     public function buildCalendar()
     {
         /**
          * Determine the calendar month and create an array of 
          * weekday abbreviations to labe the calendar columns
          */
         $cal_month = date('F Y',  strtotime($this->_useDate));
         $weekdays = array(
             'Sun','Mon', 'Tue',
             'Wed','Thu','Fri','Sat'
         );
         
         /**
          * Add a header to the calendar markup
          */
         $html = "\n\t<h2>$cal_month</h2>";
         for ($d = 0, $labels=NULL; $d < 7; ++$d) {
             $labels .= "\n\t\t<li>" .$weekdays[$d] . "</li>";
         }
         $html .= "\n\t<ul class=\"weekdays\">" . $labels . "\n\t</ul>";
         
         /**
          * Reurn the markup for output
          */
         return $html;
     }
}
?>
